#include "bo_activacio.h"
#include "parser.h"

void ba_ini(activation_bloc *ab)
{
	ab->elements=0;
	ab->last_element=0;
	ab->first_element=0;
	ab->posMemLliure=0;
	ab->tmp_var=0;
}

/*
 return -1 if the list is full
 and 0 in other case
*/
int ba_new_element (activation_bloc *ab, Node_ba nou)
{
	if (ab->elements < MAX_ELEM)
	{
	ab->llista_elem[ab->last_element].posicio = nou.posicio;
	strcpy(ab->llista_elem[(ab->last_element)].desc,nou.desc);
	ab->llista_elem[ab->last_element].mida = nou.mida;
	(ab->last_element)++;
	(ab->elements)++;
	return(0);
	}
	else return(-1);
}

/* Reset the read index of the list */
void ba_reset_read_index(activation_bloc *ab)
{
	(ab->next_element)=0;
}

/* 	
   return -1 if the list has not more elements to read
   and 0 in other case
*/
int ba_get_next(activation_bloc *ab, Node_ba *elem)
{
	if ((ab->next_element) < (ab->elements))
	{
		elem->posicio = ab->llista_elem[ab->next_element].posicio;
		strcpy(elem->desc,ab->llista_elem[ab->next_element].desc);
		elem->mida =ab->llista_elem[ab->next_element].mida;
		(ab->next_element)++;		
		return(0);
	} 
	return(-1);
}

int ba_has_more_elements(activation_bloc *ab)
{
	if ((ab->next_element) >= (ab->elements)) return(0);
	return(1);
}

/* Indicates the number of elements stored at List */
int ba_element_value(activation_bloc *ab)
{
	return(ab->elements);
}

void ba_set_pos_parameters(activation_bloc *ab, int pos)
{
	ab->parameters = pos;
}

int ba_get_pos_parameters(activation_bloc *ab)
{
  int pos;
	pos = ab->parameters;
	return(pos);
}

void ba_set_pos_data(activation_bloc *ab, int pos)
{
	ab->data = pos;
}

int ba_get_pos_data(activation_bloc *ab)
{
  int pos;
	pos = ab->data;
	return(pos);
}

int ba_obtenir_mida(int id)
{
  switch(id)
	{
	case LONG: return(8);break;/*long*/
	case INT: return(4);break;/*int*/
	case BOOLEAN: return(4);break;/*boolean*/
	case SHORT: return(2);break;/*short*/
	case CHAR: return(1);break;/*char*/
	case DOUBLE: return(8);break;/*double*/
	case FLOAT: return(8);break;/*float*/
	}
	return(0);
}

int ba_get_posMem_Lliure(activation_bloc *ab)
{
	return(ab->posMemLliure);
}

int ba_Inc_MemLliure(activation_bloc *ab, int mem)
{
    int posicio;
    posicio=ab->posMemLliure;
	ab->posMemLliure = ab->posMemLliure + mem;
    return posicio;
}

void ba_set_nom(activation_bloc *ab, char *nom, int type)
{
  	ab->type = type;
  	strcpy(ab->nom, nom);
}

void ba_get_temp(activation_bloc *ab, char *nom, int tipus)
{
 Node_ba nba;
 	sprintf(nom, "$t%i",ab->tmp_var);
 	ab->tmp_var = ab->tmp_var + 1;
	strcpy(nba.desc,nom);
/*
	nba.mida = ba_obtenir_mida(tipus);
	nba.posicio = ba_get_posMem_Lliure(ab);
	ba_Inc_MemLliure(ab,nba.mida);
	ba_new_element(ab, nba);
*/
	/*printf("Declarada var %s\n",nba.desc);	*/
 
}


void ba_get_unary_op(char *opsrc, char *opdst, int tipus)
{
	switch(tipus)
	{
	case CHAR :{
                if (strcmp("-",opsrc)==0){strcpy(opdst,"OP_NO_PERMITED");}
                else if (strcmp("!",opsrc)==0){strcpy(opdst,"OP_NO_PERMITED");}
			  }break; /*char*/
	case SHORT :{
                if (strcmp("-",opsrc)==0){strcpy(opdst,"CHSS");}
                else if (strcmp("!",opsrc)==0){strcpy(opdst,"NOTS");}
			  }break; /*short*/
	case INT :{ 
                if (strcmp("-",opsrc)==0){strcpy(opdst,"CHSI");}				
                else if (strcmp("!",opsrc)==0){strcpy(opdst,"NOTI");}				
			  }break; /*int*/
	case LONG :{
                if (strcmp("-",opsrc)==0){strcpy(opdst,"CHSL");}
                else if (strcmp("!",opsrc)==0){strcpy(opdst,"NOTL");}
			  }break; /*long*/
	case FLOAT :{
                if (strcmp("-",opsrc)==0){strcpy(opdst,"CHSF");}
                else if (strcmp("!",opsrc)==0){strcpy(opdst,"NOTF");}
			  }break; /*float*/
	case DOUBLE :{
                if (strcmp("-",opsrc)==0){strcpy(opdst,"CHSD");}
                else if (strcmp("!",opsrc)==0){strcpy(opdst,"NOTD");}
			  }break;/*double*/

	case CHARACTER_CONSTANT: {
                if (strcmp("-",opsrc)==0){strcpy(opdst,"OP_NO_PERMITED");}
                else if (strcmp("!",opsrc)==0){strcpy(opdst,"OP_NO_PERMITED");}
			  }break;/*char constant*/
	case INTEGER_CONSTANT: {
                if (strcmp("-",opsrc)==0){strcpy(opdst,"CHSI");}
                else if (strcmp("!",opsrc)==0){strcpy(opdst,"NOTI");}
			  }break;/*int constant*/

	case FLOATING_CONSTANT: {
                if (strcmp("-",opsrc)==0){strcpy(opdst,"CHSF");}
                else if (strcmp("!",opsrc)==0){strcpy(opdst,"NOTF");}
			  }break;/*float constant*/

	default:{ strcpy(opdst,"OP_NO_PERMITED");}break;
	}
}

char get_leter_type(int tipus){
    char d;
    switch(tipus)
    {
        case CHAR :{d='C';}break; /*char*/
        case SHORT :{d='S';}break; /*short*/
        case INT :{d='I';}break; /*int*/
        case LONG :{d='L';}break; /*long*/
        case FLOAT :{d='F';}break; /*float*/
        case DOUBLE :{d='D';}break;/*double*/
        case CHARACTER_CONSTANT: {d='C';}break;/*char constant*/
        case INTEGER_CONSTANT: {d='I';}break;/*int constant*/
        case FLOATING_CONSTANT: {d='F';}break;/*float constant*/
        default:{ d='E';}break;
    }
    return d;
}

void ba_get_unary_cast(char *opdst, int tipus,int tipus2)
{
    char o;
    char d;

    o=get_leter_type(tipus);
    d=get_leter_type(tipus2);

    sprintf(opdst,"%c2%c",o,d);
    printf("VALOR FINAL ====> %s\n",opdst) ;
}


void ba_get_binary_op(char *opsrc, char *opdst, int tipus)
{
	switch(tipus)
	{
	case CHAR :{if (strcmp("+",opsrc)==0){strcpy(opdst,"ADDC");}
			   if (strcmp("*",opsrc)==0){strcpy(opdst,"MULC");}
			   if (strcmp("-",opsrc)==0){strcpy(opdst,"SUBC");}
			   if (strcmp("/",opsrc)==0){strcpy(opdst,"DIVC");}
			   if (strcmp("%",opsrc)==0){strcpy(opdst,"MODC");}
			  }break; /*char*/
	case SHORT :{if (strcmp("+",opsrc)==0){strcpy(opdst,"ADDS");}
			   if (strcmp("*",opsrc)==0){strcpy(opdst,"MULS");}
			   if (strcmp("-",opsrc)==0){strcpy(opdst,"SUBS");}
			   if (strcmp("/",opsrc)==0){strcpy(opdst,"DIVS");}
			   if (strcmp("%",opsrc)==0){strcpy(opdst,"MODS");}
			  }break; /*short*/
	case INT :{if (strcmp("+",opsrc)==0){strcpy(opdst,"ADDI");}
			   if (strcmp("*",opsrc)==0){strcpy(opdst,"MULI");}
			   if (strcmp("-",opsrc)==0){strcpy(opdst,"SUBI");}
			   if (strcmp("/",opsrc)==0){strcpy(opdst,"DIVI");}
			   if (strcmp("%",opsrc)==0){strcpy(opdst,"MODI");}
			  }break; /*int*/
	case LONG :{if (strcmp("+",opsrc)==0){strcpy(opdst,"ADDL");}
			   if (strcmp("*",opsrc)==0){strcpy(opdst,"MULL");}
			   if (strcmp("-",opsrc)==0){strcpy(opdst,"SUBL");}
			   if (strcmp("/",opsrc)==0){strcpy(opdst,"DIVL");}
			   if (strcmp("%",opsrc)==0){strcpy(opdst,"MODL");}
			  }break; /*long*/
	case FLOAT :{if (strcmp("+",opsrc)==0){strcpy(opdst,"ADDF");}
			   if (strcmp("*",opsrc)==0){strcpy(opdst,"MULF");}
			   if (strcmp("-",opsrc)==0){strcpy(opdst,"SUBF");}
			   if (strcmp("/",opsrc)==0){strcpy(opdst,"DIVF");}
			   if (strcmp("%",opsrc)==0){strcpy(opdst,"MODF");}
			  }break; /*float*/
	case DOUBLE :{if (strcmp("+",opsrc)==0){strcpy(opdst,"ADDD");}
			   if (strcmp("*",opsrc)==0){strcpy(opdst,"MULD");}
			   if (strcmp("-",opsrc)==0){strcpy(opdst,"SUBD");}
			   if (strcmp("/",opsrc)==0){strcpy(opdst,"DIVD");}
			   if (strcmp("%",opsrc)==0){strcpy(opdst,"MODD");}
			  }break;/*double*/

	case CHARACTER_CONSTANT :{if (strcmp("+",opsrc)==0){strcpy(opdst,"ADDC");}
			   				  if (strcmp("*",opsrc)==0){strcpy(opdst,"MULC");}
			   				  if (strcmp("-",opsrc)==0){strcpy(opdst,"SUBC");}
			   				  if (strcmp("/",opsrc)==0){strcpy(opdst,"DIVC");}
			   				  if (strcmp("%",opsrc)==0){strcpy(opdst,"MODC");}
			  }break;/*constant char*/

	case INTEGER_CONSTANT :{if (strcmp("+",opsrc)==0){strcpy(opdst,"ADDI");}
			   if (strcmp("*",opsrc)==0){strcpy(opdst,"MULI");}
			   if (strcmp("-",opsrc)==0){strcpy(opdst,"SUBI");}
			   if (strcmp("/",opsrc)==0){strcpy(opdst,"DIVI");}
			   if (strcmp("%",opsrc)==0){strcpy(opdst,"MODI");}
			  }break;/*constant int*/

	case FLOATING_CONSTANT :{if (strcmp("+",opsrc)==0){strcpy(opdst,"ADDF");}
			   if (strcmp("*",opsrc)==0){strcpy(opdst,"MULF");}
			   if (strcmp("-",opsrc)==0){strcpy(opdst,"SUBF");}
			   if (strcmp("/",opsrc)==0){strcpy(opdst,"DIVF");}
			   if (strcmp("%",opsrc)==0){strcpy(opdst,"MODF");}
			  }break;/*constant float*/

	default:{ strcpy(opdst,"OP_NO_PERMITED");}break;
	}
}

void ba_reset_out(activation_bloc *ab, char nom_arxiu[])
{
  FILE *fout;

	fout=fopen(nom_arxiu,"w");
	if (fout==NULL) 
		{ printf("Arxiu %s impossible d'obrir\n", nom_arxiu);
		  return;}
	else 
		{fclose(fout);}
}
	

/* Take out to an archive the elements contained at List */
void ba_write_out(activation_bloc *ab, char nom_arxiu[])
{
  FILE *fout;
  Node_ba elem;
  
	
	fout=fopen(nom_arxiu,"a");
	if (fout==NULL) 
		{ printf("Arxiu %s impossible d'obrir\n", nom_arxiu);
		  return;}
	else 
	{
	fprintf(fout,"******* Elements at RA %s *******\n",ab->nom);
 	ba_reset_read_index(ab);
	while (ba_has_more_elements(ab))
	{
		ba_get_next(ab,&elem);
		
		fprintf(fout,"posicio: %i",elem.posicio);
		fprintf(fout,"\tDesc: %s",elem.desc);
		fprintf(fout,"\tMida: %i\n",elem.mida);
		
	}
	fprintf(fout,"**********************************\n");	
	}	  
	fclose(fout);	  
}

void ba_mostrar(activation_bloc *ab)
{
 Node_ba elem;
 
 	ba_reset_read_index(ab);
 	printf("******* Elements at list %i *******\n",ba_element_value(ab));
	while (ba_has_more_elements(ab))
	{
		ba_get_next(ab,&elem);
		printf("posicio: %i",elem.posicio);
		printf("\tDesc: %s",elem.desc);
		printf("\tMida: %i\n",elem.mida);
		
	}
	printf("**********************************\n");
}
